

package Planejamento.Caminho;

import GUI.Controle;
import java.awt.Rectangle;
import java.util.ArrayList;
import Mapeamento.QuadTree.No;

public class Caminho
{
    ArrayList<No> lista = new ArrayList<No>();
    No noFinal, noInicio;
    Controle controle;
    Grafo mapa;
    Dijkstra melhor;

    public Caminho(Controle x, ArrayList<No> lista)
    {
       controle = x;
       this.lista = lista;
       mapa = new Grafo();
    }

    public boolean identificarInicio(int x, int y)
    {
        Rectangle celula;
        for(No aux: lista)
        {
            celula = new Rectangle((aux.p2.x), (aux.p1.y), (aux.p1.x-aux.p2.x), (aux.p1.x-aux.p2.x));
            if(celula.contains(x, y))
            {
                aux.setNoInicio(true);
                noInicio = aux;
                mapa.getInicio(noInicio);
                return true;
            }
        }
        return false;
    }

    public boolean identificarFinal(int x, int y)
    {
        Rectangle celula;
        for(No aux: lista)
        {
            celula = new Rectangle((aux.p2.x), (aux.p1.y), (aux.p1.x-aux.p2.x), (aux.p1.x-aux.p2.x));
            if(celula.contains(x, y))
            {
                aux.setNoFinal(true);
                noFinal = aux;
                mapa.getFim(noFinal);
                return true;
            }
        }
        return false;
    }

    public void identificarVizinhos()
    {

       Rectangle celula, celula2;

       for(No aux: lista)
       {
            // Cria retangulo da celula
            celula = new Rectangle((aux.p2.x-2), (aux.p1.y-2), ((aux.p1.x-aux.p2.x)+3), ((aux.p1.x-aux.p2.x)+3));

            if(!mapa.listaNo.contains(aux))
            {
                mapa.addNo(aux);
            }

            for(int i = 0; i<lista.size(); i++)
            {
                No aux2 = lista.get(i);
                celula2 = new Rectangle(aux2.p2.x, aux2.p1.y, (aux2.p1.x-aux2.p2.x), (aux2.p1.x-aux2.p2.x));
                //System.out.println("\nId: " + aux2.id + " X: " + celula2.x + " Y: " +celula2.y + " A/L: " + celula2.height);
                if(celula.intersects(celula2))
                {
                    //System.out.println("Vizinho: " + aux2.id);
                    if(aux2.p2.x<aux.p2.x && aux2.p1.y<aux.p1.y)
                    {
                        //System.out.println("Quina 1");
                    }else if(aux2.p2.x == aux.p1.x && aux2.p2.y == aux.p1.y)
                    {
                        //System.out.println("Quina 2");
                    }else if(aux2.p1.x == aux.p2.x && aux2.p1.y == aux.p2.y)
                    {
                        //System.out.println("Quina 3");
                    }else if(aux2.p1.x>aux.p1.x && aux2.p2.y>aux.p2.y)
                    {
                        //System.out.println("Quina 4");
                    }else
                    {
                        if(aux.id != aux2.id)
                        {
                           if(!mapa.listaNo.contains(aux2))
                           {
                               mapa.addNo(aux2);
                           }
                           mapa.addAresta(aux, aux2, distanciaPontos(aux, aux2));
                           desenhaGrafo(aux, aux2);
                        }
                    }
                }
            }
       }
    }

 /* Calculo da distancia entre dois pontos do grafo
  * Estrutura de um No:
  *     _____P1
  *     |     |
  *     |  x  |
  *     |     |
  *    P2-----
  */
    public double distanciaPontos(No a, No b)
    {
        double dist, xa, ya, xb, yb;
        double t1, t2;

        xa = (int)((a.p1.x - a.p2.x)/2)+a.p2.x;
        ya = (int)((a.p2.y - a.p1.y)/2)+a.p1.y;
        xb = (int)((b.p1.x - b.p2.x)/2)+b.p2.x;
        yb = (int)((b.p2.y - b.p1.y)/2)+b.p1.y;

        t1 = (xa - xb);
        t2 = (ya - yb);

        dist = Math.sqrt(t1*t1 + t2*t2);
        return dist;
    }

    public void melhorCaminho()
    {
        melhor = new Dijkstra(mapa);
        melhor.algoritmo();
        imprimeMenorCaminhoFinal();
    }

     // Desenha todo o trajeto do caminho
    public void imprimeMenorCaminhoFinal() {

        int temp = 0;
        for (int i=0; i <melhor.caminho.size()-1; i++)
        {
            temp = i;
            i++;
            desenhaMelhor(melhor.caminho.get(temp), melhor.caminho.get(i));
            i--;
        }
    }

    // Metodo para desenhar a linha do caminho de um no ao outro, ou seja, de uma
    // celula a outra.
    public void desenha(No atual, No prox)
    {
           controle.setaLinhaCaminho(((atual.p1.x-atual.p2.x)/2+atual.p2.x), ((atual.p2.y-atual.p1.y)/2+atual.p1.y),
                   ((prox.p1.x-prox.p2.x)/2+prox.p2.x), ((prox.p2.y-prox.p1.y)/2+prox.p1.y));
    }

    public void desenhaMelhor(No atual, No prox)
    {
           controle.setaLinhaMelhorCaminho(((atual.p1.x-atual.p2.x)/2+atual.p2.x), ((atual.p2.y-atual.p1.y)/2+atual.p1.y),
                   ((prox.p1.x-prox.p2.x)/2+prox.p2.x), ((prox.p2.y-prox.p1.y)/2+prox.p1.y));
    }

    public void desenhaGrafo(No atual, No prox)
    {
           controle.setaLinhaGrafo(((atual.p1.x-atual.p2.x)/2+atual.p2.x), ((atual.p2.y-atual.p1.y)/2+atual.p1.y),
                   ((prox.p1.x-prox.p2.x)/2+prox.p2.x), ((prox.p2.y-prox.p1.y)/2+prox.p1.y));
    }
}
